<template>
	<div id="organization" class='list tree'>
		<Breadcrumb separator=">">
      <BreadcrumbItem to="">系统维护</BreadcrumbItem>
      <BreadcrumbItem to="/system/organization">机构管理</BreadcrumbItem>
  	</Breadcrumb>

		<div class="data-content">
			<div class="tree-box">
				<Card dis-hover :padding="15">
					<p slot="title"><Icon type="ios-list-outline"></Icon> 机构树</p>
					<Tree ref="tree" :data="orgTreeData"></Tree>
				</Card>
				<Spin size="large" fix v-if="isLoading"></Spin>
			</div>

			<div class="org-box">
				<Card dis-hover :padding="15">
					<p slot="title">{{modalTitle}}</p>
					<Form :label-width="120" :model="form" :rules="rules" ref="form">
						<FormItem label="机构名称" prop="orgName">
							<Input v-model="form.orgName" :disabled="!modalIsEdit" :maxlength="30" placeholder="请填写机构名称"></Input>
						</FormItem>
						<FormItem prop="loginName">
							<span slot="label">
								管理员账号 <Poptip trigger="hover" content="默认密码：账号+888"><Icon type="help-circled"></Icon></Poptip>
							</span>
							<Row>
								<Col :md="18">
									<Input v-model="form.loginName" :maxlength="20" :disabled="canEditLoginName" placeholder="请填写管理员账号"></Input>
								</Col>
								<Col :md="3" :offset="1">
									<Button v-if="form.id" type="primary" icon="refresh" @click="resetPwd">重置密码</Button>
								</Col>
							</Row>
						</FormItem>
						<FormItem label="机构类型" prop="orgType">
							<Select v-model="form.orgType" :disabled="canEditLoginName" placeholder="请选择类型" style="width:20%">
									<Option :value="1" :key="`type-option-1`">普通机构</Option>
	                <Option :value="2" :key="`type-option-2`">车队</Option>
					    </Select>
						</FormItem>
						<FormItem label="菜单权限" prop="resId">
							<div class="org-detail-tree">
								<Input v-model="form.resId" />
								<Tree ref="tree" :data="formTree" show-checkbox @on-check-change="authTreeChange"></Tree>
							</div>
						</FormItem>
						<FormItem label="联系人" prop="contactor">
							<Input v-model="form.contactor" :maxlength="20" :disabled="!modalIsEdit" placeholder="请填写联系人"></Input>
						</FormItem>
						<FormItem label="联系电话" prop="contactPhone">
							<Input v-model="form.contactPhone" :maxlength="11" :disabled="!modalIsEdit" placeholder="请填写联系电话"></Input>
						</FormItem>
						<FormItem label="电子邮箱" prop="contactEmail">
							<Input v-model="form.contactEmail" :maxlength="30" :disabled="!modalIsEdit" placeholder="请填写电子邮箱"></Input>
						</FormItem>
						<FormItem label="地理位置" prop="address">
							<Input v-model="form.address" :disabled="!modalIsEdit" placeholder="请点击地图标注地理位置" @on-change="getLocation"></Input>
							<input type="hidden" v-model="form.lng" />
							<input type="hidden" v-model="form.lat" />
						</FormItem>
						<FormItem>
							<div id="js_org_map" style="height:250px;"></div>
						</FormItem>
						<FormItem v-if="modalIsEdit">
	            <Button type="primary" :loading="isSubmiting" @click="saveOrg">
								<span v-if="!isSubmiting">提交</span>
        				<span v-else>保存中...</span>
							</Button>
							<Button type="ghost" @click="cancelEdit" :disabled="isSubmiting" style="margin-left: 8px">取消</Button>
		        </FormItem>
					</Form>
				</Card>
				<Spin size="large" fix v-if="isModalLoading"></Spin>
			</div>
		</div>

	</div>
</template>

<style lang="less" src="@/assets/styles/customize.less"></style>
<style lang="less" scoped>
	#organization {
		.tree-box{
			.ivu-tree{
				overflow-y: auto;
			}
		}
		.org-detail-tree{
	    line-height:1.2;
			.ivu-input-wrapper{
				display: none;
			}
	  }
	}
</style>

<script >
	import {mapState,mapActions} from 'vuex'
  import Map from '@/plugin/Map'

	let map, marker = null;
	export default {
		mounted(){
      map = new Map('js_org_map', {
          resizeEnable: true,
          zoom: 13,
          center: [116.397428, 39.90923]
      });
			AMap.event.addListener(map, 'click', e => {
				if (!this.modalIsEdit) return; // 没启用编辑不执行
				let p = e.lnglat;
				if (marker === null) marker = new AMap.Marker({map,position:p});
				marker.setPosition(p);
				this.setAddress([p.lng,p.lat]);
			});
		},
		data(){
			return {
				modalTitle:'',
				modalIsEdit:false,
				orgTreeData: [],
				orgTreeSelected: {},
				form: {resId:null,address:null},
				formTree:[],
				rules: {
					orgName:{required:true, message:'机构名称必填', trigger:'blur'},
					loginName:{required:true, message:'管理员账号必填', trigger:'blur'},
					resId:{required:true, message:'请至少分配一项权限', trigger:'change'},
					orgType:{required:true, type:'number', message:'请至少选择一个类型', trigger:'change'},
					address:{validator:(rule, value, cb) => {
						if (!this.form.lng && !this.form.lat){
							cb('请输入正确的地址或点击地图选择地址')
						}else{
							cb();
						}
					}, trigger:'blur'},
					contactPhone:{pattern:/^1[3|4|5|7|8][0-9]{9}$/,message:'必须是有效手机号码',trigger:'change'},
					contactEmail:{type:'email',message:'请输入正确的电子邮箱地址',trigger:'change'}
				}
			}
		},
		computed:{
			...mapState('base',['userinfo']),
			...mapState('system/organization',['orgList','orgDetail','isLoading','isModalLoading','isSubmiting']),
			canEditLoginName(){
				return !(this.modalIsEdit && !this.form.id);
			},
			authReadonly(){
				return this.orgTreeSelected.id === this.userinfo.employee.orgId;
			}
		},
		watch: {
			orgList() {
				this.orgTreeData = this.createTreeList(null);
			},
			orgTreeSelected(v) {
				this.showView();
			},
			orgDetail(v) {
				this.form = {resId:null,address:null,...v};
			},
			form(v){
				map.clearMap();
				if (v.lng && v.lat) {
					let p = [v.lng,v.lat];
					marker = new AMap.Marker({map,position:p});
					map.setCenter(p);
				}
				// 这里只处理查看的权限树
				if (v.id && !this.modalIsEdit){
					this.form.resourceVo && this.form.resourceVo.sort((a,b) => { return a.id - b.id; });
					this.formTree = this.createAuthTree({pid:0,sources:this.form.resourceVo,selecteds:this.form.resourceVo});
					this.form.resId = this.form.resourceVo ? this.form.resourceVo.map(item => { return item.id; }).join(',') : null;
				}
			}
		},
		methods:{
			...mapActions('system/organization',['reload','loadOrg','getAddress','getParentTree','disableOrg','addOrg','editOrg','resetPassword']),
			loadPage(){
				this.orgTreeData = [];
				this.reload();
			},
			createAuthTree({pid, sources = [], selecteds = [] , readonly = true}){
				let ary = new Array();
				sources.forEach(v => {
					let checked = selecteds.filter(item => { return item.id === v.id }).length > 0;
					let o = { id:v.id, parentId:v.parentId, title:v.name, disableCheckbox:readonly, checked };
					if (o.parentId === pid) {
						o.children = this.createAuthTree({pid:o.id,sources,selecteds,readonly});
						ary.push(o);
					}

					// 由下级觉得父级是否选中
					if (o.parentId === 0 && o.children && o.children.length > 0){
						o.checked = false;
					}
				});
				return ary;
			},
			async createEditAuthTree(pid){
				let sources = pid === null ? this.form.resourceVo : await this.getParentTree(pid);
				this.formTree = this.createAuthTree({pid:0,sources,selecteds:this.form.resourceVo,readonly:this.authReadonly});
			},
			showView(){
				this.modalTitle = `查看 ${this.orgTreeSelected.name} 机构信息`;
				this.modalIsEdit = false;
				this.loadOrg(this.orgTreeSelected.id);
			},
			showEdit(){
				this.modalTitle = `编辑 ${this.orgTreeSelected.name} 机构信息`;
				this.modalIsEdit = true;
				// 这里防止从新增直接到编辑时form对象为空
				if (!this.form.id){ this.form = {resId:null,address:null,...this.orgDetail}; }
				this.createEditAuthTree(this.orgTreeSelected.pId);
				this.form.resId = this.form.resourceVo ? this.form.resourceVo.map(item => { return item.id; }).join(',') : null;
			},
			showAdd(){
				this.modalTitle = `新增 ${this.orgTreeSelected.name} 的下级机构`;
				this.modalIsEdit = true;
				map.clearMap();
				marker = null;
				this.form = {resId:null,parentId:this.orgTreeSelected.id,address:null};
				this.formTree = this.createAuthTree({pid:0,sources:this.orgDetail.resourceVo,readonly:false});
			},
			cancelEdit(){
				this.modalTitle = `查看 ${this.orgTreeSelected.name} 机构信息`;
				this.modalIsEdit = false;
				map.clearMap();
				marker = null;
				this.form = {resId:null,address:null,...this.orgDetail};
				this.$refs.form.resetFields();
			},
			async setAddress([lng,lat]) {
				this.form.lng = lng;
				this.form.lat = lat;
				let res = await this.getAddress([lng,lat]);
				if (res.length > 0) {
					this.form.address = res[0].formattedAddress;
					this.$refs.form.validateField('address');
				}
			},
			authTreeChange(nodes){
				let ary = nodes.map(v => { return [v.id,v.parentId]; });
				let lst = [];
        ary.forEach(([id,pid]) => {
          lst.push(id);
          pid && lst.push(pid);
        });
        lst = [...new Set(lst)];
				this.form.resId = lst.join(',');
			},
			async saveOrg(){
				let valid = await this.$refs.form.validate();
				if (valid) {
					let res = this.form.id ? await this.editOrg(this.form) : await this.addOrg(this.form);
					if (res.success) {
						this.$Message.success('保存成功');
						this.loadPage();
					}else{
						this.$Message.error(res.msg);
					}
				}
			},
			disabledOrg(){
				this.$Modal.confirm({
            title: '禁用确认',
            content: `是否禁用“${this.orgTreeSelected.name}”？`,
            loading: true,
            onOk:async ()=>{
              let res = await this.disableOrg(this.orgTreeSelected.id);
              if (res.success){
            		this.$Modal.remove();
            		this.loadPage();
            		this.$Message.success('禁用成功');
              }else{
								this.$Modal.remove();
								this.$Message.error(res.msg);
              }
            }
        });
			},
			resetPwd(){
				this.$Modal.confirm({
            title: '重置密码',
            content: `是否将账号“${this.form.loginName}”的密码重置为“账号+888”？`,
            loading: true,
            onOk:async ()=>{
							let res = await this.resetPassword({id:this.form.loginId,loginName:this.form.loginName});
							if (res.success) {
								this.$Modal.remove();
            		this.$Message.success('重置成功');
							} else {
								this.$Modal.remove();
								this.$Message.error(res.msg);
							}
            }
        });
			},
			createTreeList(pid) {
				let ary = [];
				this.orgList.forEach(v => {
					if (v.pId === pid) {
						let isRoot = v.pId === null;
						if (isRoot) this.orgTreeSelected = v;
						let temp = this.userinfo.lowerOrgs.find(o => o.id === v.id);
						if (temp) v.orgType = temp.orgType;
						let treeNode = {id:v.id, pid:v.pId, title:v.name, orgType:v.orgType, expand:true, isRoot, selected:isRoot, children:this.createTreeList(v.id)};
						this.createRender(treeNode, v);
						ary.push(treeNode);
					}
				});
				return ary;
			},
			// 创建节点render
			createRender(treeNode, v){
				treeNode.render = (h,{root, node, data}) => {
					let iconElement  = h('span',{
						'class':{
							'tree-icon': true
						}
					},[ treeNode.isRoot ? h('Icon', {props: {type:'ios-home'}}) : h('i',{'class':{'fa':true,'fa-truck':true}}) ]);
					let titleElement = h('span',{
						'class': {
							'ivu-tree-title': true,
							'ivu-tree-title-selected': treeNode.selected
						},
						on: {
							click: (e) => {
								let ts = document.querySelector('.ivu-tree').querySelectorAll('.ivu-tree-title');
								Array.prototype.forEach.call(ts,n => { n.classList.remove('ivu-tree-title-selected'); });
								e.target.classList.add('ivu-tree-title-selected');
								this.orgTreeSelected = v;
							}
						}
					},v.name);

					let btnEdit = h('Button', {
							props: Object.assign({}, {}, { icon: 'edit' }),
							attrs: {title: '编辑'},
							on: { click: () => { this.showEdit(); } }
					});
					let btnAdd = h('Button', {
							props: Object.assign({}, {}, { icon: 'plus-round' }),
							attrs: {title: '添加下级'},
							on: { click: () => { this.showAdd(); } }
					});
					let btnDisable = h('Button', {
							props: Object.assign({}, {}, { icon: 'trash-a' }),
							attrs: {title: '禁用'},
							on: { click: () => { this.disabledOrg(); } }
					});
					let btnbox = h('div',{
						'class':{
							'ivu-btn-group':true,
							'ivu-btn-group-small':true,
							'ivu-btn-group-circle':true
						}
					},[btnEdit,(treeNode.orgType===2?null:btnAdd),(treeNode.isRoot?null:btnDisable)]);

					return [iconElement, titleElement, btnbox];
				};
			},
			getLocation(e){
				this.form.lng = null;
				this.form.lat = null;
				if (marker !== null){
					marker.setMap(null);
					marker = null;
				}
				let v = this.form.address;
				let geo = new AMap.Geocoder();
				geo.getLocation(v,(status,result)=>{
					if (status === 'complete'){
						let ad = result.geocodes[0];
						this.form.lng = ad.location.lng;
						this.form.lat = ad.location.lat;
						if (marker === null){
							marker = new AMap.Marker({map,position:ad.location});
						} else {
							marker.setPosition(ad.location);
						}
						map.setCenter(ad.location);
					}
				});
			}
		}
	}
</script>
